/*
* ============================================================================
*  Name        : sea_queue.h
*  Part of     : Finite state machine utilities
*  Description : 
*  Version     : %version: %
*  
*
* ============================================================================
*/
/**
 * @file sea_queue.h
 * @brief
 * @ref sea::Link based @ref sea::Queue
 *
 * @ingroup AssociationUtilities
 */

#if !defined( __sea_queue_h__ )
#define __sea_queue_h__

#include "sea_list.h"

namespace sea
{
    /** 
     * @class Queue
     * @brief Queue implementation. List derivative.\b Thread \b safe.
     *
     * @ingroup AssociationUtilities
     */
    class Queue: public List
    {
    public:

        /**
         * Creates queue with the id which is address of the list
         *
         */
        Queue( ): List( this ) { }

        /**
         * Creates queue with the specified id
         *
         * @param id Association id
         *
         */
        Queue( Association id ): List( id ) { }

        ~Queue( ){ clear( ); }

        /**
         * Push element into the Queue. Ref counter will be increased automatically 
         * to hold it the list
         *
         * @param obj pointer to an object
         *
         * @return @li TRUE     On success
         * @return @li FALSE    Otherwise.
         */
        bool push( Object* obj ){ return attach_last( obj ); }
        bool push( ref< >& obj ){ return attach_last( obj.get( ) ); }

        /**
         * Pops element from the Queue. Ref counter is increased b/c element 
         * has to be alive when removed from the list
         *
         * @return pointer to an object
         */
        sea::ref< > pop( )
        {
            if ( !size( ) )
            {
                return NULL;
            }
            sea::ref< > obj = get_first( );
            
            if ( !detach( obj.get( ) ) )
            {
                return NULL;
            }

            // Dont return just obj!!!
            // Copy has to be done 1st - before local auto object 
            // gets destroyed
            return sea::ref< >( obj.get( ) );
        }

        /**
         * Peaks element from the Queue. Does not remove object from the Queue
         *
         * @return pointer to an object
         */
        sea::ref< > peak( ){ return get_first( ); }

        /**
         * Checks if Queue is empty
         *
         * @return TRUE If it does
         */
        bool is_empty( ) { return size( ) == 0; }
    };
}

#endif // #if !defined( __sea_queue_h__ )
